package com.moody.hibernate.dao;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;


import org.hibernate.LockMode;
import org.hibernate.Query;
import org.hibernate.Session;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.orm.hibernate3.support.HibernateDaoSupport;

import com.moody.hibernate.domain.CollateralInfo;
import com.moody.hibernate.domain.CustInfo;
import com.moody.hibernate.domain.DebtInfo;
import com.moody.hibernate.domain.PdH;
import com.moody.hibernate.domain.RiskReportIRDetail;
import com.moody.hibernate.domain.RiskReportREDetail;
import com.moody.init.DataDictionary;

/**
 * A data access object (DAO) providing persistence and search support for
 * DebtInfo entities. Transaction control of the save(), update() and delete()
 * operations can directly support Spring container-managed transactions or they
 * can be augmented to handle user-managed Spring transactions. Each of these
 * methods provides additional information for how to configure it for the
 * desired type of transaction control.
 * 
 * @see com.moody.hibernate.domain.DebtInfo
 * @author MyEclipse Persistence Tools
 */

public class DebtInfoDAO extends HibernateDaoSupport {
	private static final Logger log = LoggerFactory
			.getLogger(DebtInfoDAO.class);
	// property constants
	public static final String DEBT_DESC = "debtDesc";
	public static final String CUST_ID = "custId";
	public static final String CUST_NAME = "custName";
	public static final String DEBT_TYPE = "debtType";
	public static final String DEBT_SUM = "debtSum";
	public static final String CURRENCY = "currency";
	public static final String START_DATE = "startDate";
	public static final String END_DATE = "endDate";
	public static final String BUSINESS_KIND = "businessKind";
	public static final String GUARANTY_KIND = "guarantyKind";
	public static final String GROUP_LOAN_TYPE = "groupLoanType";
	public static final String INTEREST_SUM = "interestSum";
	public static final String INTEREST_CYCLE = "interestCycle";
	public static final String INTEREST_RATE = "interestRate";
	public static final String PINTEREST_RATE = "pinterestRate";
	public static final String PINTEREST_TYPE = "pinterestType";
	public static final String INTEREST_RATE_CODE = "interestRateCode";
	public static final String PINTEREST_RATE_CODE = "pinterestRateCode";
	public static final String DEFAULT_DATE = "defaultDate";
	public static final String DEFAULT_BALANCE = "defaultBalance";
	public static final String DEFAULT_INTEREST_SUM = "defaultInterestSum";
	public static final String DEFAULT_REASON = "defaultReason";
	public static final String CLASSIFY_RESULT = "classifyResult";
	public static final String CLASSIFY_DATE = "classifyDate";
	public static final String INPUT_USER_ID = "inputUserId";
	public static final String INPUT_ORG_ID = "inputOrgId";
	public static final String INPUT_DATE = "inputDate";
	public static final String UPDATE_USER_ID = "updateUserId";
	public static final String UPDATE_ORG_ID = "updateOrgId";
	public static final String UPDATE_DATE = "updateDate";

	protected void initDao() {
		// do nothing
	}

	public void save(DebtInfo transientInstance) {
		log.debug("saving DebtInfo instance");
		try {
			getHibernateTemplate().save(transientInstance);
			log.debug("save successful");
		} catch (RuntimeException re) {
			log.error("save failed", re);
			throw re;
		}
	}

	public void delete(DebtInfo persistentInstance) {
        log.debug("deleting DebtInfo instance");
        try {
            getHibernateTemplate().delete(persistentInstance);
            log.debug("delete successful");
        } catch (RuntimeException re) {
            log.error("delete failed", re);
            throw re;
        }
    }
    
	public DebtInfo findById(java.lang.String id) {
		log.debug("getting DebtInfo instance with id: " + id);
		try {
			DebtInfo instance = (DebtInfo) getHibernateTemplate().get(
					"com.moody.hibernate.domain.DebtInfo", id);
			return instance;
		} catch (RuntimeException re) {
			log.error("get failed", re);
			throw re;
		}
	}

	public List findByExample(DebtInfo instance) {
		log.debug("finding DebtInfo instance by example");
		try {
			List results = getHibernateTemplate().findByExample(instance);
			log.debug("find by example successful, result size: "
					+ results.size());
			return results;
		} catch (RuntimeException re) {
			log.error("find by example failed", re);
			throw re;
		}
	}

	public List findByProperty(String propertyName, Object value) {
		log.debug("finding DebtInfo instance with property: " + propertyName
				+ ", value: " + value);
		try {
			String queryString = "from DebtInfo as model where model."
					+ propertyName + "= ?";
			return getHibernateTemplate().find(queryString, value);
		} catch (RuntimeException re) {
			log.error("find by property name failed", re);
			throw re;
		}
	}

	public List findByDebtDesc(Object debtDesc) {
		return findByProperty(DEBT_DESC, debtDesc);
	}

	public List findByCustId(Object custId) {
		return findByProperty(CUST_ID, custId);
	}

	public List findByCustName(Object custName) {
		return findByProperty(CUST_NAME, custName);
	}

	public List findByDebtType(Object debtType) {
		return findByProperty(DEBT_TYPE, debtType);
	}

	public List findByDebtSum(Object debtSum) {
		return findByProperty(DEBT_SUM, debtSum);
	}

	public List findByCurrency(Object currency) {
		return findByProperty(CURRENCY, currency);
	}

	public List findByStartDate(Object startDate) {
		return findByProperty(START_DATE, startDate);
	}

	public List findByEndDate(Object endDate) {
		return findByProperty(END_DATE, endDate);
	}

	public List findByBusinessKind(Object businessKind) {
		return findByProperty(BUSINESS_KIND, businessKind);
	}

	public List findByGuarantyKind(Object guarantyKind) {
		return findByProperty(GUARANTY_KIND, guarantyKind);
	}

	public List findByGroupLoanType(Object groupLoanType) {
		return findByProperty(GROUP_LOAN_TYPE, groupLoanType);
	}

	public List findByInterestSum(Object interestSum) {
		return findByProperty(INTEREST_SUM, interestSum);
	}

	public List findByInterestCycle(Object interestCycle) {
		return findByProperty(INTEREST_CYCLE, interestCycle);
	}

	public List findByInterestRate(Object interestRate) {
		return findByProperty(INTEREST_RATE, interestRate);
	}

	public List findByPinterestRate(Object pinterestRate) {
		return findByProperty(PINTEREST_RATE, pinterestRate);
	}

	public List findByPinterestType(Object pinterestType) {
		return findByProperty(PINTEREST_TYPE, pinterestType);
	}

	public List findByInterestRateCode(Object interestRateCode) {
		return findByProperty(INTEREST_RATE_CODE, interestRateCode);
	}

	public List findByPinterestRateCode(Object pinterestRateCode) {
		return findByProperty(PINTEREST_RATE_CODE, pinterestRateCode);
	}

	public List findByDefaultDate(Object defaultDate) {
		return findByProperty(DEFAULT_DATE, defaultDate);
	}

	public List findByDefaultBalance(Object defaultBalance) {
		return findByProperty(DEFAULT_BALANCE, defaultBalance);
	}

	public List findByDefaultInterestSum(Object defaultInterestSum) {
		return findByProperty(DEFAULT_INTEREST_SUM, defaultInterestSum);
	}

	public List findByDefaultReason(Object defaultReason) {
		return findByProperty(DEFAULT_REASON, defaultReason);
	}

	public List findByClassifyResult(Object classifyResult) {
		return findByProperty(CLASSIFY_RESULT, classifyResult);
	}

	public List findByClassifyDate(Object classifyDate) {
		return findByProperty(CLASSIFY_DATE, classifyDate);
	}

	public List findByInputUserId(Object inputUserId) {
		return findByProperty(INPUT_USER_ID, inputUserId);
	}

	public List findByInputOrgId(Object inputOrgId) {
		return findByProperty(INPUT_ORG_ID, inputOrgId);
	}

	public List findByInputDate(Object inputDate) {
		return findByProperty(INPUT_DATE, inputDate);
	}

	public List findByUpdateUserId(Object updateUserId) {
		return findByProperty(UPDATE_USER_ID, updateUserId);
	}

	public List findByUpdateOrgId(Object updateOrgId) {
		return findByProperty(UPDATE_ORG_ID, updateOrgId);
	}

	public List findByUpdateDate(Object updateDate) {
		return findByProperty(UPDATE_DATE, updateDate);
	}

	public List findAll() {
		log.debug("finding all DebtInfo instances");
		try {
			String queryString = "from DebtInfo";
			return getHibernateTemplate().find(queryString);
		} catch (RuntimeException re) {
			log.error("find all failed", re);
			throw re;
		}
	}

	public DebtInfo merge(DebtInfo detachedInstance) {
		log.debug("merging DebtInfo instance");
		try {
			DebtInfo result = (DebtInfo) getHibernateTemplate().merge(
					detachedInstance);
			log.debug("merge successful");
			return result;
		} catch (RuntimeException re) {
			log.error("merge failed", re);
			throw re;
		}
	}

	public void attachDirty(DebtInfo instance) {
		log.debug("attaching dirty DebtInfo instance");
		try {
			getHibernateTemplate().saveOrUpdate(instance);
			log.debug("attach successful");
		} catch (RuntimeException re) {
			log.error("attach failed", re);
			throw re;
		}
	}

	public void attachClean(DebtInfo instance) {
		log.debug("attaching clean DebtInfo instance");
		try {
			getHibernateTemplate().lock(instance, LockMode.NONE);
			log.debug("attach successful");
		} catch (RuntimeException re) {
			log.error("attach failed", re);
			throw re;
		}
	}

	public static DebtInfoDAO getFromApplicationContext(ApplicationContext ctx) {
		return (DebtInfoDAO) ctx.getBean("DebtInfoDAO");
	}

	
	public void update(DebtInfo transientInstance) {
		log.debug("updating DebtInfo instance");
		try {
			getHibernateTemplate().update(transientInstance);
			log.debug("update successful");
		} catch (RuntimeException re) {
			log.error("update failed", re);
			throw re;
		}
	}

	@SuppressWarnings("unchecked")
	public List<DebtInfo> findDebtByCondition(String custName,String custType, String custScope, 
			String industryType, String exposureType, String orgCode,String debtNo, String debtDesc,
			String debtType, String guarantyKind, String classifyResult, String classifyDate) {
		List<DebtInfo> resultList = new ArrayList<DebtInfo>();
		String hql = "from DebtInfo as d, CustInfo as c where d.custId = c.custId and d.custName like :custName and d.debtNo like :debtNo and d.debtDesc like :debtDesc " +
				"and d.debtType like :debtType and d.guarantyKind like :guarantyKind and d.classifyResult like :classifyResult and d.classifyDate like :classifyDate " + 
				"and c.custType like :custType and c.custScope like :custScope and c.industryType like :industryType and c.exposureType like :exposureType and c.inputOrgId like :orgCode";
		Session session = getHibernateTemplate().getSessionFactory().openSession();
		Query query = session.createQuery(hql);
		
		query.setString("custName", "%"+custName+"%");
		query.setString("custType", "%"+custType+"%");
		query.setString("custScope", "%"+custScope+"%");
		query.setString("industryType", "%"+industryType+"%");
		query.setString("exposureType", "%"+exposureType+"%");
		query.setString("orgCode", "%"+orgCode+"%");
		query.setString("debtNo", "%"+debtNo+"%");
		query.setString("debtDesc", "%"+debtDesc);
		query.setString("debtType", "%"+debtType+"%");
		query.setString("guarantyKind", "%"+guarantyKind+"%");
		query.setString("classifyResult", "%"+classifyResult+"%");
		query.setString("classifyDate", "%"+classifyDate+"%");
		
		List<Object> list = query.list();
		for(Object item :list){
			Object[] items = (Object[]) item;
			resultList.add((DebtInfo)items[0]);
		}
		session.close();
		return resultList;
	}
	
	@SuppressWarnings("unchecked")
	public List<Object> findDebtByCondition(Map<String,String> custCondition, Map<String,String> debtCondition){
		String hql = "FROM DebtInfo AS d, CustInfo AS c WHERE d.custId = c.custId";
		Set<String> custKeySet = custCondition.keySet();
		Set<String> debtKeySet = debtCondition.keySet();
		Iterator<String> it = custKeySet.iterator();
		while(it.hasNext()){
			String key = it.next();
			hql += " AND c."+ key + " LIKE :c"+key;
		}
		it = debtKeySet.iterator();
		while(it.hasNext()){
			String key = it.next();
			hql += " AND d."+ key + " LIKE :d"+key;
		}
		Session session = getHibernateTemplate().getSessionFactory().openSession();
		Query query = session.createQuery(hql);
		
		it = custKeySet.iterator();
		while(it.hasNext()){
			String key = it.next();
			query.setString("c"+key, "%" + custCondition.get(key) + "%");
		}
		it = debtKeySet.iterator();
		while(it.hasNext()){
			String key = it.next();
			query.setString("d"+key, "%" + debtCondition.get(key) + "%");
		}
		List<Object> list = query.list();
		session.close();
		return list;
		
		
	}
	
	public List<RiskReportREDetail> findREDetailByCondition(String queryCustType2,String date,String orgId,String userId,String currency){
		List<RiskReportREDetail> resultList = new ArrayList<RiskReportREDetail>();
		
		String custTypeInString = "'01','02','03'";//查询不包含零售客户
		if("01".equals(queryCustType2)) custTypeInString = "'01','02'";//对公客户
		else if("02".equals(queryCustType2))custTypeInString = "'03'";//同业客户
		
		String hql = "from DebtInfo as d, CustInfo as c where d.custId = c.custId and c.custType in (" + custTypeInString+ ") and d.updateDate like :date and d.updateUserId like :userId and d.updateOrgId like :orgId and d.currency = '" +currency + "'";
		Session session = getHibernateTemplate().getSessionFactory().openSession();
		Query query = session.createQuery(hql);
		query.setString("date", "%"+date+"%");
		query.setString("orgId", "%" +orgId+"%");
		query.setString("userId", "%"+userId+"%");
		
		List<Object> list = query.list();
		for(Object item:list){
			Object[] a = (Object[]) item;
			@SuppressWarnings("unused")
			DebtInfo debtInfo = (DebtInfo) a[0];
			@SuppressWarnings("unused")
			CustInfo custInfo = (CustInfo) a[1];
			RiskReportREDetail re = new RiskReportREDetail();
			
			re.setArea("");//待确定！
			re.setCustID(custInfo.getCustId());
			re.setCustName(custInfo.getCustName());
			re.setDebtBalance("" + debtInfo.getDebtBalance());
			re.setDebtNo(debtInfo.getDebtNo());
			re.setDebtType(DataDictionary.getInstance().getNameByCodeAndId("DebtType", debtInfo.getDebtType()));
			re.setExposureType(custInfo.getExposureType());
			re.setIndustryType(DataDictionary.getInstance().getNameByCodeAndId("IndustryType", custInfo.getIndustryType()));
			re.setOperator(debtInfo.getUpdateUserId());
			re.setSystemPDLevel(custInfo.getCreditLevel());
			
			resultList.add(re);
			
		}
		session.close();
		return resultList;
	}

}